查看原文
其他

如何在ASP.NET Core 5 中生成 PDF

DotNet 2021-09-23

The following article is from 码农读书 Author 码农读书

大家用 ASP.NET Core 进行项目开发时,常会有生成 PDF 的需求,那如何生成呢?这篇文章我们就来讨论如何通过 DinkToPdf 来生成 PDF 文档,DinkToPdf 封装了 C++ 的 wkhtmltopdf 工具包,前者通过 P/Invoke 的方式来调用后者,而底层的 wkhtmltopdf 利用 Qt WebKit 渲染引擎将 html 转成 pdf。

安装 DinkToPdf

要想安装 DinkToPdf,可以通过 Nuget 可视化界面或者通过 NuGet Package Manager Console 命令行工具输入以下命令:

Install-Package DinkToPdf  
  

安装完毕之后可以验证下 DinkToPdf.dll 是否已成功引用到项目中。

既然是封装了 C++ 的 wkhtmltopdf,肯定要拿到原生的 wkhtmltopdf 工具包, 官方下载地址:https://wkhtmltopdf.org/downloads.html ,也可以在 DinkToPdf 的官方Github:https://github.com/rdvojmoc/DinkToPdf/tree/master/v0.12.4  上下载,然后根据你的需要选择 32bit 还是 64bit 。

注册 DinkToPdf

要想在 ASP.NET Core 中使用,需要在 ConfigureServices() 方法下将 DinkToPdf 注入到 IOC 容器中,下面的代码展示了如何去实现。

        public void ConfigureServices(IServiceCollection services)  
        {  
            services.AddSingleton(typeof(IConverter),new SynchronizedConverter(new PdfTools()));  
  
            services.AddControllers();  
        }  

创建 ReportService

基础配置做好之后,接下来我们来写生成 PDF 的业务逻辑,创建一个 IReportService 和 ReportService 实现类,代码如下:

    public interface IReportService  
    {  
        public byte[] GeneratePdfReport();  
    }  
  
    public class ReportService : IReportService  
    {  
        private readonly IConverter _converter;  
        public ReportService(IConverter converter)  
        {  
            _converter = converter;  
        }  
        public byte[] GeneratePdfReport()  
        {  
            throw new NotImplementedException();  
        }  
    }  

从上面的代码可以看出,IConverter 实例是通过 构造函数 注入的,接下来可以在 GeneratePdfReport() 方法中构建生成 pdf 的具体业务逻辑。

        public byte[] GeneratePdfReport()  
        {  
            var html = $@"  
                           <!DOCTYPE html>  
                           <html lang=""en"">  
                           <head>  
                               This is the header of this document.  
                           </head>  
                          <body>  
                          <h1>This is the heading for demonstration purposes only.</h1>  
                          <p>This is a line of text for demonstration purposes only.</p>  
                          </body>  
                          </html>  
                          "
;  
            GlobalSettings globalSettings = new GlobalSettings();  
            globalSettings.ColorMode = ColorMode.Color;  
            globalSettings.Orientation = Orientation.Portrait;  
            globalSettings.PaperSize = PaperKind.A4;  
            globalSettings.Margins = new MarginSettings { Top = 25, Bottom = 25 };  
            ObjectSettings objectSettings = new ObjectSettings();  
            objectSettings.PagesCount = true;  
            objectSettings.HtmlContent = html;  
            WebSettings webSettings = new WebSettings();  
            webSettings.DefaultEncoding = "utf-8";  
            HeaderSettings headerSettings = new HeaderSettings();  
            headerSettings.FontSize = 15;  
            headerSettings.FontName = "Ariel";  
            headerSettings.Right = "Page [page] of [toPage]";  
            headerSettings.Line = true;  
            FooterSettings footerSettings = new FooterSettings();  
            footerSettings.FontSize = 12;  
            footerSettings.FontName = "Ariel";  
            footerSettings.Center = "This is for demonstration purposes only.";  
            footerSettings.Line = true;  
            objectSettings.HeaderSettings = headerSettings;  
            objectSettings.FooterSettings = footerSettings;  
            objectSettings.WebSettings = webSettings;  
            HtmlToPdfDocument htmlToPdfDocument = new HtmlToPdfDocument()  
            {  
                GlobalSettings = globalSettings,  
                Objects = { objectSettings },  
            };  
            return _converter.Convert(htmlToPdfDocument);  
        }  

然后再将 IReportService 和 ReportService 注入到 IOC 容器中,如下代码所示:

services.AddSingleton<IReportService, ReportService>();  

创建 ReportController

GeneratePdfReport() 方法的业务逻辑构建好之后,现在可以将 IReportService 实例注入到 ReportController 中来最终渲染 pdf,下面的代码展示了如何去实现。

    [Route("api/[controller]")]  
    [ApiController]  
    public class ReportController : ControllerBase  
    {  
        private readonly IReportService _reportService;  
        public ReportController(IReportService reportService)  
        {  
            _reportService = reportService;  
        }  
        [HttpGet]  
        public IActionResult Get()  
        {  
            var pdfFile = _reportService.GeneratePdfReport();  
            return File(pdfFile,"application/octet-stream""SimplePdf.pdf");  
        }  
    }  


在 ASP.NET Core 中并没有内置对 pdf 的支持,所以有这方面的需求只能借助于第三方框架,而 DinkToPdf 就是这么一款非常优秀的工具包,DinkToPdf 是一款用 .NET 语言编写的用于包装 C++ 的 wkhtmltopdf 的工具包,它可以非常方便的将 Html 转成 PDF ,

关于更多 DinkToPdf 可参考 Github:https://github.com/rdvojmoc/DinkToPdf


- EOF -

推荐阅读  点击标题可跳转

C# 9 record 并非简单属性 POCO 的语法糖

.NET 开源配置组件 AgileConfig 初体验AppDomain实现【插件式】开发


看完本文有收获?请转发分享给更多人

推荐关注「DotNet」,提升.Net技能 

点赞和在看就是最大的支持❤️

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存